//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.Activities
{
	#region Using Directives

	using System;
	using System.Collections.Generic;
	using System.Text;
	using System.ComponentModel;
	using System.Workflow.ComponentModel;
	using System.Collections;
	using System.Collections.Specialized;
	using System.Workflow.ComponentModel.Design;
	using System.ComponentModel.Design;
	using Microsoft.Research.ScientificWorkflow.NetCDF.CSharpAPI;
	using System.Workflow.ComponentModel.Compiler;

    using Microsoft.Research.ScientificWorkflow;
    using Microsoft.Research.ScientificWorkflow.Helpers;
    
    using WorkflowData;
	#endregion

    [Name("Variable Value Clamper")]
    [Description("Transform for clamping variable values within a specified range")]
    [WorkflowCategory("NetCdf")]
    public class ClampingActivity : Activity
	{
		#region Dependency Property
		public static DependencyProperty VariablesProperty = DependencyProperty.Register("Variables", 
            typeof(string), typeof(ClampingActivity));

        [RequiredInputParam]
        [Name("Clamping Variables", "Clamping Variable Details")]
        [Description("List of clamping variables. Only numeric variables are supported.")]
		public string Variables
		{
			get
			{
				return ((string)(base.GetValue(ClampingActivity.VariablesProperty)));
			}
			set
			{
				base.SetValue(ClampingActivity.VariablesProperty, value);
			}
		}

        public static DependencyProperty InputCubeProperty =
            DependencyProperty.Register("InputCube", typeof(HyperCube), typeof(ClampingActivity));

        [RequiredInputParam]
        [Name("In Hyper Cube")]
        [Description("Hyper Cube for Cleaning")]
        public HyperCube InputCube
        {
            get
            {
                return ((HyperCube)(base.GetValue(ClampingActivity.InputCubeProperty)));
            }
            set
            {
                base.SetValue(ClampingActivity.InputCubeProperty, value);
            }
        }

        public static DependencyProperty OutCubeProperty =
            DependencyProperty.Register("OutCube", typeof(HyperCube), typeof(ClampingActivity));

        [OutputParam]
        [Name("Resultant Hyper Cube")]
        [Description("Cleaned cube containing data with cleaned values.")]
        public HyperCube OutCube
        {
            get
            {
                return ((HyperCube)(base.GetValue(ClampingActivity.OutCubeProperty)));
            }
            set
            {
                base.SetValue(ClampingActivity.OutCubeProperty, value);
            }
        }        

        #endregion

		#region Overriden Methods

		protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
		{
			IHyperCubeTransform xTransf = new ClampingTransform();
            this.OutCube = xTransf.Transform(this.InputCube, this.GetClampingVariables());

			return ActivityExecutionStatus.Closed;
		}

		#endregion

        #region Private Methods

        /// <summary>
        /// This method parses the string argument to generate an array of
        /// clamping variables to be passed as argument to the transform.
        /// </summary>
        /// <returns>Array of clamping variables</returns>
        private ClampingVariable[] GetClampingVariables()
        {
            string[] v = (this.Variables).Split(new char[] { ',' });
            if (v.Length == 0 || (0 != v.Length%4))
                throw new ArgumentException("Argument Error for variables specified for clamping");

            ClampingVariable[] varArray = new ClampingVariable[v.Length / 4];
            for (int i = 0,j=0; i < v.Length; j++)
            {
                ClampingVariable var = new ClampingVariable();
                var.VariableName = v[i];
                var.MinValue = v[i + 1];
                var.MaxValue = v[i + 2];
                var.OptionalValue = v[i + 3];
                varArray[j] = var;
                i += 4;
            }
            return varArray;
        }

        #endregion
    }
}
